﻿using FB.Membership.Annotations;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Configuration.Provider;
using System.Linq;
using System.Text;
using System.Web.Security;

namespace FB.Membership.Providers
{
    public abstract class AspNetPermissionProvider : ProviderBase
    {
        public abstract List<Permission> GetUserPermissions(MembershipUser user);
        public abstract List<Permission> GetUserPermissions(MembershipUser user, bool includeRole);
        public abstract List<Permission> GetRolePermissions(string roleName);
        public abstract List<Permission> GetRolesPermissions(params string[] rolesName);
        public abstract List<string> FindUserHasPermission<P>(P permFlag);

        public abstract bool Validate<P>(List<Permission> permList, P permFlag);
        public abstract bool ValidateModule<M>(List<Permission> permList, M module);
        public abstract bool AnyOf<P>(List<Permission> permList);
        public abstract void AddToUser<P>(MembershipUser user, P permFlag) where P : struct;
        public abstract void AddToRole<P>(string roleName, P permFlag) where P : struct;
        public abstract void RemoveFromRole<P>(string roleName, P permFlag) where P : struct;
        public abstract void RemoveFromUser<P>(MembershipUser user, P permFlag) where P : struct;
        public abstract void RemoveAllFromUser(MembershipUser user);


        public static void IsEnumWithFlags(Type type)
        {
            if (!type.IsEnum)
                throw new ArgumentException(string.Format("Type '{0}' is not an enum", type.FullName));
            if (!Attribute.IsDefined(type, typeof(SecurityFlagAttribute)))
                throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'SecurityFlag' attribute", type.FullName));
        }


        public static SecurityFlagAttribute GetSecurityFlag<T>(T perm)
        {
            var type = perm.GetType();
            return GetSecurityFlag(type);
        }


        public static SecurityFlagAttribute GetSecurityFlag(Type type)
        {
            IsEnumWithFlags(type);
            object[] attributes = type.GetCustomAttributes(typeof(SecurityFlagAttribute), false);
            return attributes.First() as SecurityFlagAttribute;
        }

    }



}
